package cn.iocoder.yudao.module.contract.service.contractTemplate;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.contract.dal.dataobject.client.ClientDO;
import cn.iocoder.yudao.module.contract.dal.dataobject.contractType.ContractTypeDO;
import cn.iocoder.yudao.module.contract.dal.dataobject.frameworkAgreement.FrameworkAgreementDO;
import cn.iocoder.yudao.module.contract.dal.mysql.client.ClientMapper;
import cn.iocoder.yudao.module.contract.dal.mysql.contractType.ContractTypeMapper;
import cn.iocoder.yudao.module.contract.dal.mysql.frameworkAgreement.FrameworkAgreementMapper;
import cn.iocoder.yudao.module.contract.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.annotations.VisibleForTesting;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import cn.iocoder.yudao.module.contract.controller.admin.contractTemplate.vo.*;
import cn.iocoder.yudao.module.contract.dal.dataobject.contractTemplate.ContractTemplateDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.contract.dal.mysql.contractTemplate.ContractTemplateMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.contract.enums.ErrorCodeConstants.*;

/**
 * 合同模板 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class ContractTemplateServiceImpl extends ServiceImpl<ContractTemplateMapper, ContractTemplateDO> implements ContractTemplateService {

    @Resource
    private ContractTemplateMapper templateMapper;
    @Resource
    private ContractTypeMapper templateTypeMapper;
    @Resource
    private ClientMapper clientMapper;

    @Override
    public Long createTemplate(ContractTemplateSaveReqVO createReqVO) {
        //校验唯一
        if(!"Backups".equals(createReqVO.getContractTypeCode())){
            validateUnique(createReqVO.getId(),createReqVO);
        }
        // 插入
        ContractTemplateDO template = BeanUtils.toBean(createReqVO, ContractTemplateDO.class);
        ContractTypeDO contractTypeDO = templateTypeMapper.selectOne(new LambdaQueryWrapper<ContractTypeDO>().eq(ContractTypeDO::getCode,createReqVO.getContractTypeCode()));
        template.setContractTypeName(contractTypeDO.getName());
        if(ObjectUtil.isNotEmpty(createReqVO.getClientId())){
            ClientDO clientDO = clientMapper.selectById(createReqVO.getClientId());
            if(clientDO!=null){
                template.setClientName(clientDO.getClientName());
                template.setClientCode(clientDO.getClientCode());
            }
        }else{
            template.setClientName(null);
            template.setClientCode(null);
        }
        templateMapper.insert(template);
        // 返回
        return template.getId();
    }

    @Override
    public void updateTemplate(ContractTemplateSaveReqVO updateReqVO) {
        //校验唯一
         if(!"Backups".equals(updateReqVO.getContractTypeCode())){
            validateUnique(updateReqVO.getId(),updateReqVO);
        }
        // 校验存在
        validateTemplateExists(updateReqVO.getId());
        // 更新
        ContractTemplateDO updateObj = BeanUtils.toBean(updateReqVO, ContractTemplateDO.class);
        ContractTypeDO contractTypeDO = templateTypeMapper.selectOne(new LambdaQueryWrapper<ContractTypeDO>().eq(ContractTypeDO::getCode,updateReqVO.getContractTypeCode()));
        updateObj.setContractTypeName(contractTypeDO.getName());
        if(ObjectUtil.isNotEmpty(updateObj.getClientId())){
            ClientDO clientDO = clientMapper.selectById(updateObj.getClientId());
            if(clientDO!=null){
                updateObj.setClientName(clientDO.getClientName());
                updateObj.setClientCode(clientDO.getClientCode());
            }
        }else{
            updateObj.setClientName(null);
            updateObj.setClientCode(null);
        }
        templateMapper.updateById(updateObj);
    }

    @Override
    public void deleteTemplate(Long id) {
        // 校验存在
        validateTemplateExists(id);
        // 删除
        templateMapper.deleteById(id);
    }

    private void validateTemplateExists(Long id) {
        if (templateMapper.selectById(id) == null) {
            throw exception(TEMPLATE_NOT_EXISTS);
        }
    }
    @VisibleForTesting
    void validateUnique(Long id, ContractTemplateSaveReqVO saveReqVO) {
        String contractTypeCode = saveReqVO.getContractTypeCode();
        if (StrUtil.isBlank(contractTypeCode)) {
            return;
        }
        ContractTemplateDO data = templateMapper.selectOne(new LambdaQueryWrapper<ContractTemplateDO>()
                .eq(ContractTemplateDO::getContractTypeCode,contractTypeCode).eq(ObjectUtil.isNotEmpty(saveReqVO.getClientId()),ContractTemplateDO::getClientId,saveReqVO.getClientId())
                .isNull(ObjectUtil.isEmpty(saveReqVO.getClientId()),ContractTemplateDO::getClientId));
        if (data == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的用户
        if (id == null) {
            throw exception(TEMPLATE_EXISTS);
        }
        if (!data.getId().equals(id)) {
            throw exception(TEMPLATE_EXISTS);
        }
    }


    @Override
    public ContractTemplateDO getTemplate(Long id) {
        return templateMapper.selectById(id);
    }

    @Override
    public PageResult<ContractTemplateDO> getTemplatePage(ContractTemplatePageReqVO pageReqVO) {
        return templateMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ContractTemplateDO> getTemplateList(ContractTemplateDO templateDO) {
        return templateMapper.selectList(new LambdaQueryWrapperX<ContractTemplateDO>()
                .likeIfPresent(ContractTemplateDO::getContractTypeName, templateDO.getContractTypeName())
                .likeIfPresent(ContractTemplateDO::getContractName, templateDO.getContractName())
                .eqIfPresent(ContractTemplateDO::getContractCode, templateDO.getContractCode())
                .orderByDesc(ContractTemplateDO::getId));
    }

}